package services

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"regexp"
	"strings"

	openai "github.com/openai/openai-go" // Correct import
	"github.com/openai/openai-go/option" // Correct import
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
	hunyuan "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/hunyuan/v20230901"
)

// 中医提示词模板
const TCM_PROMPT = `你是一位拥有几十年经验的中医专家，擅长中医辨证论治。
请根据用户描述的症状，提供专业的中医分析和建议。
回答需要包括：
1. 可能的中医证型诊断
2. 相关中医理论解释
3. 推荐的药膳、穴位或生活调理建议
4. 必要的注意事项

请使用专业但通俗易懂的语言，回答应体现中医的整体观和辨证论治思想。
如果症状可能涉及严重疾病，请建议用户及时就医。
`

// HunyuanResponse 定义非流式响应结构体
type HunyuanResponse struct {
	Choices []struct {
		Message struct {
			Content string `json:"content"`
		} `json:"message"`
	} `json:"choices"`
	// 其他可能的字段，根据实际响应结构补充
}

// HunyuanStreamResponse 定义流式响应结构体
type HunyuanStreamResponse struct {
	Choices []struct {
		Delta struct {
			Content string `json:"Content"`
		} `json:"Delta"`
	} `json:"Choices"`
}

// GetAIResponse 调用腾讯混元大模型API获取回复(非流式)
func GetAIResponse(query string) (string, error) {
	// 构造 client
	client := openai.NewClient(
		option.WithAPIKey(os.Getenv("HUNYUAN_API_KEY")),                 // 混元 APIKey
		option.WithBaseURL("https://api.hunyuan.cloud.tencent.com/v1/"), // 混元 endpoint
	)

	// 自定义参数传参示例
	completion, err := client.Chat.Completions.New(context.Background(),
		openai.ChatCompletionNewParams{
			Messages: openai.F([]openai.ChatCompletionMessageParamUnion{
				openai.SystemMessage(TCM_PROMPT),
				openai.UserMessage(query),
			}),
			Model: openai.F("hunyuan-turbo"),
		},
		option.WithJSONSet("enable_enhancement", true), // <- 自定义参数
	)
	if err != nil {
		return "", fmt.Errorf("调用 API 失败: %v", err)
	}

	// 将响应转换为 HunyuanResponse 结构体
	var response HunyuanResponse
	data, err := json.Marshal(completion)
	if err != nil {
		return "", fmt.Errorf("序列化响应数据失败: %v", err)
	}
	err = json.Unmarshal(data, &response)
	if err != nil {
		return "", fmt.Errorf("解析响应 JSON 失败: %v", err)
	}

	// 检查响应中是否有有效的回复内容
	if len(response.Choices) > 0 {
		return response.Choices[0].Message.Content, nil
	}

	return "", fmt.Errorf("未获取到有效的回复内容")
}

// GetStreamingAIResponse 调用腾讯混元大模型API获取流式响应
func GetStreamingAIResponse(query string, streamChan chan string) (string, error) {
	// 从环境变量获取密钥信息
	secretId := os.Getenv("HUNYUAN_SECRET_ID")
	secretKey := os.Getenv("HUNYUAN_SECRET_KEY")

	// 实例化一个认证对象
	credential := common.NewCredential(secretId, secretKey)

	// 实例化一个client选项
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "hunyuan.tencentcloudapi.com"

	// 实例化要请求产品的client对象
	client, err := hunyuan.NewClient(credential, "", cpf)
	if err != nil {
		return "", fmt.Errorf("创建客户端失败: %v", err)
	}

	// 实例化一个请求对象
	request := hunyuan.NewChatCompletionsRequest()

	// 设置模型和开启流式响应
	request.Model = common.StringPtr("hunyuan-turbo-latest")
	request.Stream = common.BoolPtr(true)

	// 设置消息内容，包含系统提示词和用户查询
	messages := []*hunyuan.Message{
		{
			Role:    common.StringPtr("system"),
			Content: common.StringPtr(TCM_PROMPT),
		},
		{
			Role:    common.StringPtr("user"),
			Content: common.StringPtr(query),
		},
	}
	request.Messages = messages

	// 发送流式请求
	response, err := client.ChatCompletions(request)
	if err != nil {
		return "", fmt.Errorf("调用 API 失败: %v", err)
	}

	// 用于累积完整响应
	var fullResponse strings.Builder

	// 设置一个标志，用于跟踪是否收到了任何响应
	receivedAnyResponse := false

	// 处理流式响应
	if response.Events != nil {
		for event := range response.Events {
			// 解析返回的JSON数据
			data := string(event.Data)

			var streamResp HunyuanStreamResponse
			if err := json.Unmarshal([]byte(data), &streamResp); err != nil {
				fmt.Printf("解析JSON失败: %v, 数据: %s\n", err, data)
				continue
			}
			
			if len(streamResp.Choices) > 0 {
				content := streamResp.Choices[0].Delta.Content
				receivedAnyResponse = true

				// 安全地发送到channel
				select {
				case streamChan <- content:
				}

				// 累积完整响应
				fullResponse.WriteString(content)
			}
		}
	}

	// 如果没有收到任何响应，发送一个错误消息
	if !receivedAnyResponse {
		fmt.Println("没有收到任何响应")
		select {
		case streamChan <- "抱歉，未能获取到有效回复。请稍后再试。":
			// 消息发送成功
		default:
			// channel可能已关闭
		}
	}

	return fullResponse.String(), nil
}

// FormatTCMResponse 格式化AI响应为中医风格，并处理Markdown格式
func FormatTCMResponse(response string) string {
	// 处理Markdown格式为HTML格式
	formattedResponse := response

	// 处理标题
	headerRegex := regexp.MustCompile(`(?m)^#{1,6}\s+(.+)$`)
	formattedResponse = headerRegex.ReplaceAllStringFunc(formattedResponse, func(match string) string {
		level := 0
		for i, char := range match {
			if char == '#' {
				level++
			} else {
				match = match[i:]
				break
			}
		}
		match = strings.TrimSpace(match)
		return fmt.Sprintf("<h%d>%s</h%d>", level, match, level)
	})

	// 处理粗体
	boldRegex := regexp.MustCompile(`\*\*(.+?)\*\*`)
	formattedResponse = boldRegex.ReplaceAllString(formattedResponse, "<strong>$1</strong>")

	// 处理无序列表
	unorderedListRegex := regexp.MustCompile(`(?m)^- (.+)$`)
	formattedResponse = unorderedListRegex.ReplaceAllString(formattedResponse, "<li>$1</li>")

	// 将连续的列表项包装在ul标签中
	formattedResponse = strings.ReplaceAll(formattedResponse, "</li>\n<li>", "</li><li>")
	listItemsRegex := regexp.MustCompile(`(?s)<li>.+</li>`)
	formattedResponse = listItemsRegex.ReplaceAllStringFunc(formattedResponse, func(match string) string {
		return "<ul>" + match + "</ul>"
	})

	// 处理换行和段落
	paragraphs := strings.Split(formattedResponse, "\n\n")
	for i, p := range paragraphs {
		if !strings.HasPrefix(p, "<") && p != "" {
			paragraphs[i] = "<p>" + p + "</p>"
		}
	}
	formattedResponse = strings.Join(paragraphs, "\n")

	// 确保段落间有适当的间距
	formattedResponse = strings.ReplaceAll(formattedResponse, "\n", "<br>")

	return formattedResponse
}
